package org.testis.utils.tree;

import java.awt.Color;
import javax.swing.tree.DefaultMutableTreeNode;

import org.testis.orm.refinedclasses.DynamicMapDesignTreeNode;
import org.testis.orm.refinedclasses.TestDesignTreeNode;
import org.testis.utils.tree.TreeNode;

/**
 *
 * @author Cahit Emir Erel
 */
public class MyDefaultMutableTreeNode extends DefaultMutableTreeNode {

    public static Color DEFAULT = Color.WHITE;
    public static Color COMPARE = Color.GREEN;
    public static Color EXACT = Color.WHITE;
    public static Color DIFF_PARAMETER = Color.YELLOW;
    public static Color DIFF_PROPERTY = Color.ORANGE;
    public static Color DIFF_TYPE = Color.RED;
    public static Color DIFF_NAME = Color.PINK;
    protected boolean m_isSelected = false;
    private boolean m_hasCheckBox;
    private Color m_color = Color.WHITE;
    private Color m_highlightColor = Color.MAGENTA;
    private boolean m_highlighted = false;
    private boolean m_isCheckBoxSelectable = true;

    /**
     * Constructs an empty MyDefaultMutableTreeNode
     */
    public MyDefaultMutableTreeNode(boolean hasCheckBox) {
        super();
        setHasCheckBox(hasCheckBox);
    }

    @Override
    public MyDefaultMutableTreeNode getNextSibling() {
        return (MyDefaultMutableTreeNode) super.getNextSibling();
    }

    @Override
    public MyDefaultMutableTreeNode getPreviousSibling() {
        return (MyDefaultMutableTreeNode) super.getPreviousSibling();
    }

    public void setCheckBoxSelectable(boolean selectable) {
        m_isCheckBoxSelectable = selectable;
    }

    public boolean isCheckBoxSelectable() {
        return m_isCheckBoxSelectable;
    }

    /**
     * Constructs a new MyDefaultMutableTreeNode with object reference
     * @param object - object reference
     */
    public MyDefaultMutableTreeNode(Object object,
            boolean hasCheckBox) {
        super(object);
        setHasCheckBox(hasCheckBox);
    }

    @Override
    public String toString() {
        try {
            if (getUserObject() != null) {
                String result = super.getUserObject().toString();
                int i = result.indexOf("Name:");
                if (i == -1) {
                    i = 0;
                } else {
                    i += 5;
                }
                int j = result.indexOf('\n',
                        i);
                if (j == -1) {
                    j = result.length();
                }
                return result.substring(i,
                        j);
            } else {
                return "root";
            }
        } catch (NullPointerException ex) {
            return "";
        }
    }

    /**
     * Changes the selection state of MyDefaultMutableTreeNode and any children it has
     * @param isSelected - selection state
     */
    public void setSelected(boolean isSelected) {
        m_isSelected = isSelected;
        if (getUserObject() instanceof TreeNode) {
            ((TreeNode) getUserObject()).setSelected(isSelected);
        }
        if (children != null) {
            MyDefaultMutableTreeNode node;
            for (int i = 0; i < children.size(); i++) {
                node = (MyDefaultMutableTreeNode) children.get(i);
                node.setSelected(isSelected);
                if (node.getUserObject() instanceof TreeNode) {
                    ((TreeNode) node.getUserObject()).setSelected(isSelected);
                }
            }
        }
    }

    /**
     * Changes the selection state of MyDefaultMutableTreeNode and its parent
     * @param isSelected - selection state
     */
    public void setSelectedSingle(boolean isSelected) {
        m_isSelected = isSelected;
        if (getUserObject() instanceof TreeNode) {
            ((TreeNode) getUserObject()).setSelected(isSelected);
        }
        if (getParent() != null) {
            if (isSelected) {
                getParent().setSelectedSingle(isSelected);
            } else {
                for (int i = 0; i < getParent().getChildCount(); i++) {
                    if (getParent().getChildAt(i).isSelected()) {
                        getParent().setSelectedSingle(true);
                        return;
                    }
                }
                getParent().setSelectedSingle(false);
            }
        }
    }

    /**
     * Returns the nth child of this MyDefaultMutableTreeNode
     * @param n - place of child in the children list
     * @return nth child of this MyDefaultMutableTreeNode
     */
    @Override
    public MyDefaultMutableTreeNode getChildAt(int n) {
        if (n >= 0 && n < getChildCount()) {
            return (MyDefaultMutableTreeNode) super.getChildAt(n);
        } else {
            return null;
        }
    }

    /**
     * Returns the selection state
     * @return true if this MyDefaultMutableTreeNode is selected
     */
    public boolean isSelected() {
        return m_isSelected;
    }

    /**
     * Return the parent of this MyDefaultMutableTreeNode
     * @return parent of this MyDefaultMutableTreeNode
     */
    @Override
    public MyDefaultMutableTreeNode getParent() {
        return (MyDefaultMutableTreeNode) super.getParent();
    }

    public boolean hasCheckBox() {
        return m_hasCheckBox;
    }

    public void setHasCheckBox(boolean hasCheckBox) {
        m_hasCheckBox = hasCheckBox;
    }

    public Color getColor() {
        return m_color;
    }

    public void setColor(Color color) {
        m_color = color;
    }

    public Color getHighlightColor() {
        return m_highlightColor;
    }

    public void setHighlightColor(Color highlightColor) {
        m_highlightColor = highlightColor;
    }

    public boolean isHighlighted() {
        return m_highlighted;
    }

    public void setHighlighted(boolean highlighted) {
        m_highlighted = highlighted;
    }

    public int hashCode() {
        if (getUserObject() != null) {
            if (getUserObject() instanceof TestDesignTreeNode) {
                TestDesignTreeNode node =
                        (TestDesignTreeNode) getUserObject();
                return node.getId();
            } else if (getUserObject() instanceof DynamicMapDesignTreeNode) {
                DynamicMapDesignTreeNode node =
                        (DynamicMapDesignTreeNode) getUserObject();
                return node.getId();
            }
        }
        return 0;
    }

    public boolean equals(Object arg0) {
        MyDefaultMutableTreeNode inTreeNode = (MyDefaultMutableTreeNode) arg0;
        if (getUserObject() != null) {
            if (getUserObject() instanceof TestDesignTreeNode &&
                    inTreeNode.getUserObject() instanceof TestDesignTreeNode) {
                TestDesignTreeNode node =
                        (TestDesignTreeNode) getUserObject();
                TestDesignTreeNode innode =
                        (TestDesignTreeNode) inTreeNode.getUserObject();
                if (node.getId() == innode.getId()) {
                    return true;
                }
            } else if (getUserObject() instanceof DynamicMapDesignTreeNode &&
                    inTreeNode.getUserObject() instanceof DynamicMapDesignTreeNode) {
                DynamicMapDesignTreeNode node =
                        (DynamicMapDesignTreeNode) getUserObject();
                DynamicMapDesignTreeNode innode =
                        (DynamicMapDesignTreeNode) inTreeNode.getUserObject();
                if (node.getId() == innode.getId()) {
                    return true;
                }
            }
            return false;
        }
        if (inTreeNode.getUserObject() == null && getUserObject() == null) {
            return true;
        }
        return false;
    }

    public MyDefaultMutableTreeNode searchUserObjectById(Integer id) {
        if (!(getUserObject() instanceof DynamicMapDesignTreeNode)) {
            return null;
        }
        DynamicMapDesignTreeNode node = (DynamicMapDesignTreeNode) getUserObject();
        if (node.getId() == id) {
            return this;
        }

        int childCount = super.getChildCount();
        for (int i = 0; i < childCount; i++) {
            MyDefaultMutableTreeNode result = getChildAt(i).searchUserObjectById(id);
            if (result != null) {
                return result;
            }
        }
        return null;
    }
}
